Skip to content

fix(settings): shortcut recorder stops on an outside click or window blur (#1272) - #1308

Merged
Juliusolsson05 merged 6 commits into
mainfrom
fix/shortcut-recorder-release
Sep 25, 2026
Merged

Juliusolsson05 merged 6 commits into
mainfrom
fix/shortcut-recorder-release

Conversation

@Juliusolsson05

@Juliusolsson05 Juliusolsson05 commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Fixes #1272.

Found by the Stage 3 C4 hunt. Plan: docs/plans/2026-09-25-shortcut-recorder-release.md (first commit).

Why

While recording a command shortcut, a capture-phase window listener swallows every key. It released only on Escape or a finished chord. So clicking the Settings search box and typing t silently saved T as that command's shortcut.

What merges

  • Recording ends on a mousedown outside the recorder's own button, or when the window blurs. The outside click matches HotkeyInput and MouseButtonInput. Ending on blur is stricter than HotkeyInput, which only clears held modifiers, because a recording left armed across an app switch is how a stray key got saved.
  • The listener runs in the capture phase, so a control that stops propagation cannot keep the recording armed.
  • The recorder button toggles itself: a click on it releases the recording and re-arms it rather than ending it.
  • Only the list's scrollbar is exempt (review B). The list has 134 rows in a 420 px scroller, and grabbing its scrollbar is not leaving. Only a press past the scroller's client box counts as the scrollbar (onScrollbar). A click in the scroller's own 8 px gaps between category blocks, or on a row, still ends the recording (review B, round 2).

Tests

CommandKeybindingsRow.capture.renderer.test.tsx renders the real component with the real store. It covers:

  • an outside click, which ends the recording without swallowing or saving t (red on main);
  • a blur, which ends it (red on main);
  • a scrollbar drag, which keeps it;
  • a gap click and a row click, which end it;
  • the recorder toggle;
  • a stopPropagation control.

Every mutation reviewers listed dies. npx tsc -b is clean.

🤖 Generated with Claude Code

Juliusolsson05 and others added 4 commits September 25, 2026 07:29
…lur (#1272)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dow blur (#1272)

Recording captured every key until Escape or a finished chord, so clicking
the Settings search box and typing 't' silently bound 'T' to the command.
It now ends on a mousedown outside the recorder button or a window blur,
like HotkeyInput and MouseButtonInput.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ing; release edges pinned

- B: grabbing the 134-row list's scrollbar ended recording (the mousedown
  targets the scroller, outside every recorder button), leaving the next
  chord live. A mousedown whose target IS the list scroller is exempt;
  clicks on rows still end recording.
- A/C: tests pin the recorder button's own toggle and the capture-phase
  release past a control that stops propagation (both surviving mutants).
- The comment no longer claims blur matches HotkeyInput (it is stricter).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Juliusolsson05 added a commit that referenced this pull request Sep 25, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ing, not its gaps

The scroller is also the mousedown target for its own 8 px flex gaps
between category blocks, and a click there left recording armed. Only a
press past the scroller's client box (its scrollbar) is exempt now. Tests
pin the scrollbar, the gap and a row click.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Juliusolsson05

Copy link
Copy Markdown
Owner Author

Round 2 disposition (final round), head 5077e3a

  • A and C: MERGE-READY in round 1; their findings were fixed in 09e350b.
  • B round 2 (reviewed 09e350b), both minor, both fixed in 5077e3a:
    • A click in the scroller's own 8 px flex gaps kept recording armed. Only a press past the scroller's client box, on the scrollbar, is now exempt (onScrollbar). New test: 'ends recording on a click in the gap between category blocks'.
    • No test clicked a row, so the closest mutant survived. New test: 'ends recording on a click on another row'.

No round 3 per §7.3. The PR merges on a green gate that includes current main.

🤖 Generated with Claude Code

Juliusolsson05 added a commit that referenced this pull request Sep 25, 2026
/#1312

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Juliusolsson05

Copy link
Copy Markdown
Owner Author

Gate check before merge: head 38e83b34 contains main 1d25b0ed, and quality-gate and minimum-node-fixture-gate passed. Three reviewers: A, B and C (round 2 for B). The body is updated to the merged behaviour. Merging.

🤖 Generated with Claude Code

@Juliusolsson05
Juliusolsson05 merged commit 7f273e0 into main Sep 25, 2026
2 checks passed
@Juliusolsson05
Juliusolsson05 deleted the fix/shortcut-recorder-release branch September 25, 2026 16:40
Juliusolsson05 added a commit that referenced this pull request Sep 25, 2026
…dicts, #1316

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shortcut recorder keeps capturing after focus leaves it, silently saving a bare key

1 participant